"use strict";
function SGoBoard()
{
    this.handi_19x19=[3,3,3,9,3,15,9,3,9,9,9,15,15,3,15,9,15,15];
    this.handi_13x13=[3,3,3,6,3,9,6,3,6,6,6,9,9,3,9,6,9,9];
    this.handi_9x9=[2,2,2,4,2,6,4,2,4,4,4,6,6,2,6,4,6,6];
    this.SAMECOLOR         =0;
    this.DIFFERENTCOLOR    =1;
    this.MARGIN            =2;
    this.EMPTY             =3;
    this.VISITED           =4;
    this.m_stones=null;
    this.boardSize=19;
    this.maxSize=19;
    this.m_stoneIndex=0;
    this.m_bounds=null;
}

SGoBoard.prototype.checkBounds=function(x,y)
{
    if( isNaN(x) || isNaN(y) )
    {
        return false;
    }
    if((x<0)||(x>=this.boardSize)||(y<0)||(y>=this.boardSize))
        return false;
    return true;
}

SGoBoard.prototype.setBounds=function(bounds,gap)
{ 
    this.m_bounds=bounds;
    this.m_bounds.left-=gap;
    this.m_bounds.top-=gap;
    this.m_bounds.bottom+=gap;
    this.m_bounds.right+=gap;

    if(this.m_bounds.left<0)
        this.m_bounds.left=0;    
        
    if(this.m_bounds.top<0)
        this.m_bounds.top=0;     
          
    if(this.m_bounds.right>this.boardSize)
        this.m_bounds.right=this.boardSize;
        
    if(this.m_bounds.bottom>this.boardSize)
        this.m_bounds.bottom=this.boardSize;    
}

SGoBoard.prototype.init=function(size)
{
    var i,j;
    this.boardSize=size;
    this.m_stones=new Array(this.maxSize);
    for(i=0;i<this.maxSize;i++)
    {
        this.m_stones[i]=new Array(this.maxSize);
        for(j=0;j<this.maxSize;j++)
            this.m_stones[i][j]=null;
    }
}

SGoBoard.prototype.addMove=function(stone)
{	
    
    if((stone.m_x >=0) && (stone.m_y >=0))
    {
	    this.m_stones[stone.m_x][stone.m_y]=stone;  	    	    	
	}
};

SGoBoard.prototype.remMove=function(stone)
{    
    if((stone.m_x >=0) && (stone.m_y >=0))
    {        
   		this.m_stones[stone.m_x][stone.m_y]=null;
    }
}

SGoBoard.prototype.getGroup=function(i,j)
{
    var ii,jj,st,k,ind,rv,str,haslibs,group,control;
    group=new Array();
    ind=0;
    control=0;

    st=this.m_stones[i][j];
    st.m_visited=true;
    group.push(st);

    haslibs=false;
    while(ind<group.length)
    {
        control++;
        if(control>100)
        {
            sgodebug(1,"Failed to capture stones");
            return;
        }
        for(k=0;k<4;k++)
        {
            ii=group[ind].m_x;
            jj=group[ind].m_y;
            if(k==0) ii--;
            if(k==1) jj--;
            if(k==2) ii++;
            if(k==3) jj++;
            rv=this.checkNeighbor(group[ind],ii,jj);
            if(rv==this.SAMECOLOR)
            {
                st=this.m_stones[ii][jj];
                if(st.m_visited==false)
                {
                    st.m_visited=true;
                    group.push(st);
                 }
            }
            else if(rv==this.EMPTY)
            {
                haslibs=true;
            }
        }
        ind++;
        if(haslibs) break;
    }
    str="";

    for(i=0;i<group.length;i++)
    {
       group[i].m_visited=false;
       if(haslibs==false)
       {            
            this.remMove(group[i]);
       }
    }

    if(haslibs)
        group=null;

    return group;
}


SGoBoard.prototype.checkNeighbor=function(stone,x,y)
{

    if((x<0)||(x>=this.boardSize)||(y<0)||(y>=this.boardSize))
        return this.MARGIN;   

	if(this.m_stones[x][y]==null)
	    return this.EMPTY;	    
    if(this.m_stones[x][y].m_visited)
       return this.VISITED;	       
    if((this.m_stones[x][y].m_color==stone.m_color))
    {                          
        return this.SAMECOLOR;
    }
    else
        return this.DIFFERENTCOLOR;
}

SGoBoard.prototype.createGroup=function(stone)
{
    var st,group,rv,ind,xx,yy,k,haslib;
    
    st=stone;    
    group=new Array();
    group.push(st);
    st.m_visited=true;
    ind=0;
    haslib=false;
    
    while(ind<group.length)
    {   
        for(k=0;k<4;k++)
        {
            xx=st.m_x;
            yy=st.m_y;
            if(k==0) xx--;
            if(k==1) yy--;
            if(k==2) xx++;
            if(k==3) yy++;
            rv=this.checkNeighbor(st,xx,yy)
            if((rv==this.SAMECOLOR) && this.m_stones[xx][yy].m_visited==false)
            {
                group.push(this.m_stones[xx][yy]);
                this.m_stones[xx][yy].m_visited=true;
            }
            else if(rv==this.EMPTY)
            {            
                haslib=true;
                break;
            }
        }
        ind++;
        st=group[ind];
    }
    
    if(haslib)
    {
        for(k=0;k<group.length;k++)
        {
            group[k].m_visited=false;
        }
        group=null;
    }
    return group;
}

SGoBoard.prototype.makeMove=function(node,stone)
{
    var i,j,k,rv,grp,st,xx,yy,group;	
    
    this.m_stoneIndex++;
    stone.m_index=this.m_stoneIndex;
    if(this.checkBounds(stone.m_x,stone.m_y)==false)
    {
        return;
    }
	this.addMove(stone);	

	if(node.m_capture.length>0)
	{	    
	    for(k=0;k<node.m_capture.length;k++)
	    {
	        this.remMove(node.m_capture[k]);
	    }
	}
	else
	{
	    for(k=0;k<4;k++)
        {
            xx=stone.m_x;
            yy=stone.m_y;
            if(k==0) xx--;
            if(k==1) yy--;
            if(k==2) xx++;
            if(k==3) yy++;
            if(this.checkNeighbor(stone,xx,yy)==this.DIFFERENTCOLOR)
            {
	            group=this.createGroup(this.m_stones[xx][yy]);
	            if(group!=null)
	                node.m_capture=node.m_capture.concat(group);
	        }
	     } 
	     for(k=0;k<node.m_capture.length;k++)
	     {
	        node.m_capture[k].dump();
	        node.m_capture[k].m_visited=false;
	        this.remMove(node.m_capture[k]);
	     }  	    
	 }	   
	
}

SGoBoard.prototype.takeMove=function(node,stone)
{
    var i;    
        
    this.m_stoneIndex--;

    if((node!=null) && (node.m_capture!=null))
    {
        for(i=0;i<node.m_capture.length;i++)
        {
            this.addMove(node.m_capture[i]);
        }
    }
    this.remMove(stone);
}

SGoBoard.prototype.clear=function ()
{
    var i,j;
    for(i=0;i<this.boardSize;i++)
    	for(j=0;j<this.boardSize;j++)
    	{
    		if(this.m_stones[i][j]!=null)
    		{
               this.remMove(this.m_stones[i][j]);
    		}
    	}
	this.m_stoneIndex=0;
}

SGoBoard.prototype.isHandi=function(x,y)
{
    var i,hx,hy,hstart,harr;
    hx=false;
    hy=false;
    if(this.boardSize==19)
        harr=this.handi_19x19;
    else if(this.boardSize==13)
        harr=this.handi_13x13;
    else if(this.boardSize==9)
        harr=this.handi_9x9;
    
    for(i=0;i<harr.length;i+=2)
    {
        if(x==harr[i])   
            hx=true;
        if(y==harr[i+1]) 
            hy=true;                
    }        
    return (hx && hy);
}

SGoBoard.prototype.dump=function()
{
   var i,j,str,prop,bounds;
   str=" ";
   bounds=this.m_bounds;
   
   for(j=bounds.left;j<bounds.right;j++)
      str+=' '+j%10;
   str+="\n";
   
   for(j=bounds.top;j<bounds.bottom;j++)
   {
      str+=j%10;
      for(i=bounds.left;i<bounds.right;i++)
      {
            prop=this.m_stones[i][j];
    	    if(prop!=null)
    	    {    	        
    	        if(prop.m_color==SGFProp.COLOR_BLACK)
        	        str+=' '+'#';
        	    else if(prop.m_color==SGFProp.COLOR_WHITE)
        	        str+=' '+'o';
    	    }
    	    else
    	    {
    	        if(this.isHandi(i,j))
    	            str+=' ,';
    	        else
    	           str+=' .';
    	    }
       }
       str+="\n";       
    }    
    return str;
}

